#! /usr/bin/env python
# -*- coding:utf8 -*-
# vim: ts=8 tw=4 sts=4 et
import wx
import os
import sys
from time import strftime, localtime, time
from binascii import crc32
from ctypes import c_uint32

FILE_KEY_NAME = "name"
FILE_KEY_PATH = "path"
FILE_KEY_SIZE = "size"
FILE_KEY_CRC32 = "crc32"
FILE_KEY_DATETIME = "datetime"

FILE_ITEM_COL_NAME = 0
FILE_ITEM_COL_SIZE = 1
FILE_ITEM_COL_CRC32 = 2
FILE_ITEM_COL_DATETIME = 3
FILE_ITEM_COL_PATH = 4 

FILE_ITEM_COL_KEYD = {
    FILE_ITEM_COL_PATH : FILE_KEY_PATH,
    FILE_ITEM_COL_NAME : FILE_KEY_NAME,
    FILE_ITEM_COL_SIZE : FILE_KEY_SIZE,
    FILE_ITEM_COL_CRC32 : FILE_KEY_CRC32,
    FILE_ITEM_COL_DATETIME : FILE_KEY_DATETIME,
}

FILE_ITEM_COL_MESSAGED = {
    FILE_ITEM_COL_PATH : u"파일 경로",
    FILE_ITEM_COL_NAME : u"파일 이름",
    FILE_ITEM_COL_SIZE : u"파일 크기",
    FILE_ITEM_COL_CRC32 : u"파일 CRC32",
    FILE_ITEM_COL_DATETIME : u"파일 수정 날짜-시간",
}

DEFAULT_MESSAGE = u"파일을 올려주세요"

class FileInfoManager:
    def __init__(self):
        self.fileInfods = []

    def AppendFilePath(self, filePath):
        fileDir, fileName = os.path.split(filePath)
        fileData = open(filePath, "rb").read()
        fileSize = len(fileData)
        fileMTime = os.stat(filePath).st_mtime
        fileDateTime = strftime("%Y-%m-%d %H:%M:%S", localtime(fileMTime))
        fileChecksum = c_uint32(crc32(fileData)).value

        fileInfod = {
            FILE_KEY_NAME : fileName,
            FILE_KEY_PATH : filePath,
            FILE_KEY_SIZE : "%d" % fileSize,
            FILE_KEY_CRC32 : "0x%.8x" % fileChecksum,
            FILE_KEY_DATETIME : fileDateTime,
        }

        self.fileInfods.append(fileInfod)
        return fileInfod

    def GetFileInfodAt(self, index):
        return self.fileInfods[index]

class TestFileDropTarget(wx.FileDropTarget):
    def __init__(self, fileInfoList, fileInfoMgr):
        wx.FileDropTarget.__init__(self)
        self.fileInfoList = fileInfoList
        self.fileInfoMgr = fileInfoMgr

    def OnDropFiles(self, x, y, filePaths):
        for fileIndex, filePath in enumerate(filePaths):
            fileInfod = self.fileInfoMgr.AppendFilePath(filePath)

            itemIndex = self.fileInfoList.InsertStringItem(sys.maxint, fileInfod[FILE_KEY_NAME])
            self.fileInfoList.SetStringItem(itemIndex, FILE_ITEM_COL_SIZE, fileInfod[FILE_KEY_SIZE])
            self.fileInfoList.SetStringItem(itemIndex, FILE_ITEM_COL_CRC32, fileInfod[FILE_KEY_CRC32])
            self.fileInfoList.SetStringItem(itemIndex, FILE_ITEM_COL_DATETIME, fileInfod[FILE_KEY_DATETIME])
            self.fileInfoList.SetStringItem(itemIndex, FILE_ITEM_COL_PATH, fileInfod[FILE_KEY_PATH])

class MainPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
      
        self.selectedIndex = -1
        self.selectedColumn = -1
        self.fileInfoMgr = FileInfoManager()

        self.label = wx.StaticText(self, -1, DEFAULT_MESSAGE)

        fileInfoList = wx.ListCtrl(self, -1, style = wx.LC_REPORT| wx.LC_SINGLE_SEL)

        fileInfoList.InsertColumn(FILE_ITEM_COL_NAME, "name")
        fileInfoList.InsertColumn(FILE_ITEM_COL_SIZE, "size")
        fileInfoList.InsertColumn(FILE_ITEM_COL_CRC32, "crc32")
        fileInfoList.InsertColumn(FILE_ITEM_COL_DATETIME, "datetime")
        fileInfoList.InsertColumn(FILE_ITEM_COL_PATH, "path")

        fileInfoList.SetColumnWidth(FILE_ITEM_COL_NAME, 100)
        fileInfoList.SetColumnWidth(FILE_ITEM_COL_SIZE, 100)
        fileInfoList.SetColumnWidth(FILE_ITEM_COL_CRC32, 100)
        fileInfoList.SetColumnWidth(FILE_ITEM_COL_DATETIME, 150)
        fileInfoList.SetColumnWidth(FILE_ITEM_COL_PATH, 200)

        fileInfoList.SetDropTarget(TestFileDropTarget(fileInfoList, self.fileInfoMgr))
        fileInfoList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.__OnSelectItem)
        fileInfoList.Bind(wx.EVT_LIST_COL_CLICK, self.__OnSelectColumn)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.label, 0, wx.ALL, 5)
        sizer.Add(fileInfoList, 1, wx.ALL|wx.EXPAND, 5)
        self.SetSizer(sizer)

    def __OnSelectItem(self, evt):
        self.selectedIndex = evt.GetIndex()
        self.__PrintSelectedFileInfo()

    def __OnSelectColumn(self, evt):
        self.selectedColumn = evt.GetColumn() 
        self.__PrintSelectedFileInfo()

    def __PrintSelectedFileInfo(self):
        if self.selectedIndex >= 0:
            fileInfod = self.fileInfoMgr.GetFileInfodAt(self.selectedIndex)
            
            selectedFileName = fileInfod[FILE_KEY_NAME]
            if self.selectedColumn >= 0:
                selectedColumnText = FILE_ITEM_COL_MESSAGED[self.selectedColumn]
                selectedInfoValue = fileInfod[FILE_ITEM_COL_KEYD[self.selectedColumn]]
                if self.selectedColumn:
                    self.label.SetLabel("%s:%s:%s" % (selectedColumnText, selectedFileName, selectedInfoValue))
                else:
                    self.label.SetLabel("%s:%s" % (selectedColumnText, selectedFileName))

                if wx.TheClipboard.Open():
                    do = wx.TextDataObject()
                    do.SetText(str(selectedInfoValue))
                    wx.TheClipboard.SetData(do)
                    wx.TheClipboard.Close()
        else:
            if self.selectedColumn >= 0:
                selectedColumnText = FILE_ITEM_COL_MESSAGED[self.selectedColumn]
                self.label.SetLabel("%s:%s" % (selectedColumnText, DEFAULT_MESSAGE))
    
class MainFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title)
        self.CentreOnScreen(wx.BOTH)
        panel = MainPanel(self)
        panel.Layout()

class MainApp(wx.App):
    def OnInit(self):
        frame = MainFrame(None, "Main Frame")
        frame.Show()
        self.SetTopWindow(frame)
        return True

    def OnExit(self):
        pass

if __name__ == "__main__":
    MainApp(redirect=False).MainLoop()
